import socket
import tkinter as tk
from tkinter import scrolledtext, ttk
import threading

class SocketClient:
    def __init__(self, root):
        self.root = root
        self.root.title("Socket 客户端")
        self.root.geometry("450x400")
        
        # 设置界面
        self.setup_ui()
        
        # 客户端状态
        self.client_socket = None
        self.connected = False
        
        # 绑定按钮事件
        self.connect_button.config(command=self.toggle_connection)
        self.send_button.config(command=self.send_message, state=tk.DISABLED)
        self.message_entry.bind("<Return>", lambda event: self.send_message())
    
    def setup_ui(self):
        # 服务器连接设置区
        connection_frame = ttk.Frame(self.root, padding="10")
        connection_frame.pack(fill=tk.X)
        
        ttk.Label(connection_frame, text="服务器主机:").pack(side=tk.LEFT, padx=5)
        self.host_entry = ttk.Entry(connection_frame, width=20)
        self.host_entry.pack(side=tk.LEFT, padx=5)
        self.host_entry.insert(0, socket.gethostname())
        
        ttk.Label(connection_frame, text="端口:").pack(side=tk.LEFT, padx=5)
        self.port_entry = ttk.Entry(connection_frame, width=10)
        self.port_entry.pack(side=tk.LEFT, padx=5)
        self.port_entry.insert(0, "12345")
        
        self.connect_button = ttk.Button(connection_frame, text="连接")
        self.connect_button.pack(side=tk.LEFT, padx=5)
        
        # 消息显示区
        ttk.Label(self.root, text="消息记录:").pack(anchor=tk.W, padx=10)
        self.message_area = scrolledtext.ScrolledText(self.root, wrap=tk.WORD, width=50, height=15)
        self.message_area.pack(padx=10, pady=5, fill=tk.BOTH, expand=True)
        self.message_area.config(state=tk.DISABLED)
        
        # 消息输入区
        input_frame = ttk.Frame(self.root, padding="10")
        input_frame.pack(fill=tk.X)
        
        ttk.Label(input_frame, text="输入消息:").pack(side=tk.LEFT, padx=5)
        self.message_entry = ttk.Entry(input_frame, width=40)
        self.message_entry.pack(side=tk.LEFT, padx=5, fill=tk.X, expand=True)
        
        self.send_button = ttk.Button(input_frame, text="发送")
        self.send_button.pack(side=tk.LEFT, padx=5)
    
    def log_message(self, message):
        """在消息区域显示信息"""
        self.message_area.config(state=tk.NORMAL)
        self.message_area.insert(tk.END, message + "\n")
        self.message_area.see(tk.END)  # 滚动到最后
        self.message_area.config(state=tk.DISABLED)
    
    def toggle_connection(self):
        """切换连接状态（连接/断开）"""
        if not self.connected:
            self.connect_to_server()
        else:
            self.disconnect_from_server()
    
    def connect_to_server(self):
        """连接到服务器"""
        try:
            host = self.host_entry.get()
            port = int(self.port_entry.get())
            
            self.client_socket = socket.socket()
            self.client_socket.connect((host, port))
            self.connected = True
            
            self.log_message(f"已连接到 {host}:{port}")
            self.connect_button.config(text="断开连接")
            self.send_button.config(state=tk.NORMAL)
            self.message_entry.focus()
            
            # 启动线程监听服务器回复
            threading.Thread(target=self.listen_for_response, daemon=True).start()
            
        except Exception as e:
            self.log_message(f"连接失败: {str(e)}")
            self.client_socket = None
    
    def disconnect_from_server(self):
        """断开与服务器的连接"""
        if self.connected and self.client_socket:
            try:
                self.client_socket.close()
            except Exception as e:
                self.log_message(f"断开连接时出错: {str(e)}")
            
            self.connected = False
            self.log_message("已断开连接")
            self.connect_button.config(text="连接")
            self.send_button.config(state=tk.DISABLED)
    
    def send_message(self):
        """发送消息到服务器"""
        if not self.connected or not self.client_socket:
            return
            
        message = self.message_entry.get().strip()
        if not message:
            return
            
        try:
            self.client_socket.send(message.encode('utf-8'))
            self.log_message(f"我: {message}")
            self.message_entry.delete(0, tk.END)  # 清空输入框
        except Exception as e:
            self.log_message(f"发送消息失败: {str(e)}")
            self.disconnect_from_server()
    
    def listen_for_response(self):
        """监听服务器的回复"""
        while self.connected and self.client_socket:
            try:
                data = self.client_socket.recv(1024).decode('utf-8')
                if data:
                    self.log_message(f"服务器: {data}")
                else:
                    # 没有数据，说明连接已关闭
                    self.log_message("服务器已关闭连接")
                    self.disconnect_from_server()
                    break
            except Exception as e:
                if self.connected:  # 如果不是主动断开的，才显示错误
                    self.log_message(f"接收消息时出错: {str(e)}")
                    self.disconnect_from_server()
                break

if __name__ == "__main__":
    root = tk.Tk()
    app = SocketClient(root)
    root.mainloop()














# import socket

# s= socket.socket()
# host = socket.gethostname()
# port = 12345

# s.connect((host,port))
# print(s.recv(1024).decode('utf-8'))
# s.close()